home *** CD-ROM | disk | FTP | other *** search
- /*________________________________________________________________________________
-
- BadUtils.c
-
- Copyright © 1993-1995 Onyx Technology - All rights reserved
-
- Various utility routines used by BadAPPL.
- ________________________________________________________________________________*/
-
- #ifndef _H_BadAPPL
- #include "BadAPPL.h"
- #endif
- #ifndef _H_BadUtils
- #include "BadUtils.h"
- #endif
- #ifndef _H_BadGestalt
- #include "BadGestalt.h"
- #endif
- #ifndef _H_BadGlobs
- #include "BadGlobs.h"
- #endif
- #ifndef _H_BadMacros
- #include "BadMacros.h"
- #endif
- #ifndef _H_BadErrors
- #include "BadErrors.h"
- #endif
- #ifndef _H_BadWindows
- #include "BadWindows.h"
- #endif
- #ifndef _H_QCAPI
- #include "QCAPI.h"
- #endif
- #ifdef USESROUTINEDESCRIPTORS
- #include <LowMem.h>
- #endif
-
- /*________________________________________________________________________________
-
- MaintainCursor()
-
- info: Maintain the cursor based upon where it is on the screen.
- ________________________________________________________________________________*/
-
- void MaintainCursor(void)
- {
- // if we had different cursors to maintain, this is where we would do it.
- // because BadAPPL does allow editing of the TextEdit record (huh?) we dont
- // need and dont use the I-beam cursor.
- }
-
-
- /*________________________________________________________________________________
-
- SetUpMenus()
-
- info: Initialize our menus and build the menu bar
- Please note that there are much more automatic ways to setup all our menus,
- this example was coded this way to remain as simplistic as possible.
-
- return: false if the menu couldn't be built.
- ________________________________________________________________________________*/
- short SetUpMenus(void)
- {
- QCTestPtr testListP;
- MenuHandle menuH;
- long testCnt;
- short loop, result = true; // default to an okay status
-
- gTestListH = QCGetTestList(&gTestCnt);
-
- gMenus[appleM] = GetMenu(kAppleID);
- if (!gMenus[appleM])
- result = false;
-
- AddResMenu(gMenus[appleM], 'DRVR');
-
- // if any one of these GetMenu calls fails, we all fail!
-
- if (result && !(gMenus[fileM] = GetMenu(kFileID)))
- result = false;
- if (result && !(gMenus[editM] = GetMenu(kEditID)))
- result = false;
- if (result && !(gMenus[controlM] = GetMenu(kControlID)))
- result = false;
- else
- {
- if (gTestListH)
- {
- testCnt = gTestCnt;
- menuH = gMenus[controlM];
- HLock((Handle)gTestListH);
- testListP = *gTestListH;
- while (testCnt)
- {
- // Safely append menu titles by first appending an item with a dummy
- // name, then changing the name to the test. This avoids slashes that
- // may appear in test names showing up w/command keys next to them.
-
- AppendMenu(menuH, "\pdummy");
- SetItem(menuH, CountMItems(menuH), testListP->testName);
- testListP++;
- testCnt--;
- }
- HUnlock((Handle)gTestListH);
- }
- }
-
- if (result && !(gMenus[errorsM] = GetMenu(kErrorsID)))
- result = false;
- if (result && !(gMenus[stateM] = GetMenu(kStateID)))
- result = false;
-
- // now get our heir-menus
- if (result && !(gMenus[handleM] = GetMenu(handleID)))
- result = false;
- if (result && !(gMenus[ptrM] = GetMenu(ptrID)))
- result = false;
- if (result && !(gMenus[addrZeroM] = GetMenu(addrZeroID)))
- result = false;
- if (result && !(gMenus[purgeM] = GetMenu(purgeID)))
- result = false;
-
- if (result) // if we are still okay
- {
- // please note that we cant just go into a loop from 0 to NUM_MENUS because
- // some of the menus included in that count are heir menus. we have to include
- // them as items in a given menu, not as items in the main menu bar.
-
- for ((loop=appleM); (loop <= stateM); loop++)
- {
- // if we got to here, gMenus[] contains all needed menus, don't need to check
- // the array for !nil handle...we didn't initialize them all to nil anyway.
-
- InsertMenu(gMenus[loop], 0);
- switch (loop)
- {
- case errorsM:
- InsertMenu(gMenus[handleM], -1);
- InsertMenu(gMenus[ptrM], -1);
- InsertMenu(gMenus[addrZeroM], -1);
- InsertMenu(gMenus[purgeM], -1);
- break;
-
- // if we add more menus we can handle inserting their heir menus here
- }
- }
-
- DrawMenuBar();
- }
-
- return(result);
- }
-
- /*________________________________________________________________________________
-
- MaintainMenus()
-
- info: Update the menus by enabling/disabling items as needed.
-
- ________________________________________________________________________________*/
- void MaintainMenus(void)
- {
- long testCnt;
-
- if (gQCInstalled) // we are installed, enable items & menus
- {
- if (QCIsActive())
- SetItem(gMenus[fileM], onCommand, "\pTurn QC™ Off");
- else
- SetItem(gMenus[fileM], onCommand, "\pTurn QC™ On");
-
- testCnt = gTestCnt;
- do
- MaintainControlMenu(testCnt, kCheckMenus);
- while(testCnt--);
-
- if (gQCSavedStateH) // is there state info present?
- {
- DisableItem(gMenus[stateM], saveCommand);
- EnableItem(gMenus[stateM], restoreCommand);
- }
- else
- {
- EnableItem(gMenus[stateM], saveCommand);
- DisableItem(gMenus[stateM], restoreCommand);
- }
- }
- else // disable all these items & menus
- {
- SetItem(gMenus[fileM], onCommand, "\pQC™ Not Loaded");
- DisableItem(gMenus[fileM], onCommand);
-
- DisableItem(gMenus[controlM], 0);
- DisableItem(gMenus[stateM], 0);
- }
- }
-
- /*________________________________________________________________________________
- MaintainControlMenu()
-
- info: Handle the Control (tests) menu by performing two important
- functions for BadAPPL.
-
- entry: theItem - menu item to work with
- controlCmd - test if the particular test is on (kCheckState)
- set/clear the particular test (kDoState)
- ________________________________________________________________________________*/
- void MaintainControlMenu(short theItem, short controlCmd)
- {
- QCTestPtr testP;
- QCType testID;
- long state;
- short err;
- Boolean checkIt;
-
- if ((theItem < 0) || (theItem > gTestCnt))
- return;
-
- testP = *(gTestListH); // point to the first one
- testP += (theItem-1); // advance to the desired QCTestRec
- testID = testP->testID; // and grab that test’s testID
-
- err = QCGetTestState(testID, &state); // Now test whether that test is active or not
- if (err)
- OutputString( kErrStringsID, kQCGetTestState, (long) err);
- else
- {
- switch (controlCmd)
- {
- case kCheckMenus:
- if (state)
- checkIt = true;
- else
- checkIt = false;
- CheckItem(gMenus[controlM], theItem, checkIt);
- break;
-
- case kDoState:
- QCSetTestState(testID, !state); // just toggle it on/off
- break;
- }
- }
- }
-
- /*________________________________________________________________________________
-
- DoDialog()
-
- info: Display a given dialog and handle events by calling ModalDialog and
- dispose of it properly when the user exits. DoDialog can be used for
- dialogs that don't require user interaction within the dialog, other
- than clicking on a button to dismiss it.
-
- ________________________________________________________________________________*/
- short DoDialog(short DLOGid)
- {
- DialogPtr my_dialog;
- short item_hit = 0;
- short type;
- Rect boxT;
- GrafPtr savePort;
- Handle temp_H;
- Point dlgOrigin;
-
- if (!gAtleastSys7) // if we are pre 7.0, we need to
- CenterDialog('DLOG', DLOGid, &dlgOrigin); // center it ourselves
-
- if ((my_dialog = GetNewDialog(DLOGid, 0, (WindowPtr)-1L)))
- {
- ShowWindow(my_dialog); // because we have it initially
- // inivisible in the DLOG tmpl
- GetPort( &savePort);
- SetPort(my_dialog);
-
- // Here we do a quick modification to this otherwise generic dialog display code.
- // If we're compiling for PowerPC, then we want code that checks if we're displaying
- // the About dialog so we can display a small PowerPC logo (if available). Of course
- // if this wasn't just a sample, we'd check for monitor depth and display the right
- // picture for that depth so we always look good. As it is now, things don't look as
- // neat in 1-bit mode. We don't need to extra code in this sample just to do that.
-
- #ifdef powerc
- if (DLOGid == aboutDLOG) // are we displaying the about box?
- {
- PicHandle ppcLogoH = GetPicture(kPowerPCLogo);
- if (ppcLogoH)
- {
- GetDItem(my_dialog, iPowerPCLogo, &type, &temp_H, &boxT);
- DrawPicture (ppcLogoH, &boxT);
- ReleaseResource((Handle) ppcLogoH);
- }
- }
- #endif
-
- GetDItem(my_dialog, iOkay, &type, &temp_H, &boxT);
- FrameDefault( &boxT);
-
- ModalDialog(0L, &item_hit); // go running along now until the user
- // interacts with us.
- DisposDialog(my_dialog);
-
- SetPort(savePort);
- }
-
- return(item_hit);
- }
-
- /*________________________________________________________________________________
-
- BadAlert()
-
- info: Display a generic Alert with a specified string in it. This routine
- relies on a DLOG with static text items in it and then calls DoDialog
- to display that dialog.
-
- entry: theString0 - pointer to text string to be used as Param0
- theString1 - pointer to text string to be used as Param1
- theString2 - pointer to text string to be used as Param2
- Note that ParamText allows four param strings…we only use three
-
- ________________________________________________________________________________*/
-
- void BadAlert(StringPtr theString0, StringPtr theString1, StringPtr theString2)
- {
- GrafPtr savedPort;
-
- GetPort(&savedPort);
-
- ParamText(theString0, theString1, theString2, 0L);
- DoDialog(errorDLOG);
-
- SetPort(savedPort);
- }
-
-
- /*________________________________________________________________________________
-
- CenterDialog()
-
- info: Center dialog or alert template.
- This routine
-
- entry: templateType - 'DLOG' or 'ALRT'
- templateID - the id of the rsrc template.
-
- return: true if successful; false if not
-
- ________________________________________________________________________________*/
-
- short CenterDialog( regvar long templateType, regvar short templateID, Point *dlgOrigin)
- {
- regvar Rect *dialog_rect;
- regvar Rect **the_H; // Templates start with boundsRect
- regvar short width;
- regvar short height;
- Rect scrn_rect; // the rect of the screen to center on
- GDHandle gHndl;
- RgnHandle deskRgn; // used temporarily here
- short result = true;
-
- if (ColorQDIsPresent()) // are we using Color QuickDraw?
- {
- gHndl = GetMainDevice(); // then get rect of main device
- scrn_rect = (**gHndl).gdRect; // and use it for the screen rect
- }
- else // nope, no Color QuickDraw available
- {
- deskRgn = GetGrayRgn(); // so grab the Gray region
- scrn_rect = (**deskRgn).rgnBBox; // and use its bouding box
- }
-
- if ( !(the_H = (Rect **)GetResource(templateType, templateID)) ) // try to get the DLOG or ALRT
- {
- // see ‘Macros.h’ for the Dbug macro which is only “live” if _CHECKPOINTS_ is #defined
- DbugStr("\pCenterDialog failed GetResource");
- result = false;
- }
-
- if (result)
- {
- #ifdef USESROUTINEDESCRIPTORS
- scrn_rect.top += LMGetMBarHeight();
- #else
- scrn_rect.top += MBarHeight; // add the menu bar height to the top
- #endif
- dialog_rect = *the_H; // point to the DLOG or ALRT rectangle
- // note, we dont call anything that moves memory near here so we can dereference the_H
-
- width = dialog_rect->right - dialog_rect->left;
- height = dialog_rect->bottom - dialog_rect->top;
-
- dialog_rect->top = scrn_rect.top + ((scrn_rect.bottom - scrn_rect.top - height) / 3);
- dialog_rect->bottom = dialog_rect->top + height;
- dialog_rect->left = scrn_rect.left + ((scrn_rect.right - scrn_rect.left - width) / 2);
- dialog_rect->right = dialog_rect->left + width;
-
- dlgOrigin->h = dialog_rect->left;
- dlgOrigin->v = dialog_rect->top;
- }
-
- return(result);
- }
-
- /*________________________________________________________________________________
-
- FrameDefault()
-
- info: Frames default dialog buttons (usually OK buttons)
-
- entry: r is the rect containing the button to frame
-
- ________________________________________________________________________________*/
-
- void FrameDefault( Rect *r)
- {
- Rect theRect = *r;
- GrafPtr port;
- Point savePenSize;
-
- GetPort(&port);
- savePenSize = port->pnSize;
-
- PenSize(3, 3);
- InsetRect( &theRect, -4, -4);
- FrameRoundRect( &theRect,16,16);
- PenSize(savePenSize.h, savePenSize.v);
- }
-
- char *strcpy(char *s1, char *s2);
- /*________________________________________________________________________________
-
- HexToString()
-
- info: Like NumToString except it converts the number to
- an unsigned hex string.
-
- entry: n - The long to be converted
- str - Must point to a Str255
- exit: str - Will contain an 9 character hex string, like \p00010AB4
-
- ________________________________________________________________________________*/
- void HexToString (regvar ulong number, uchar *hex)
- {
- char digits[16] = {'0','1','2','3','4','5','6','7','8','9',
- 'A','B','C','D','E','F'};
- char zeros[9] = {8,0,0,0,0,0,0,0,0};
- int n;
-
- // Get those leading zeros
- strcpy ((char *) hex, (char *) zeros);
-
- hex[0] = 8;
- for (n = 8; n >= 1; n--)
- {
- hex[n] = digits[number % 16];
- number = number / 16;
- }
- }
-
- /*________________________________________________________________________________
-
- format: void AppendString( uchar * origStr, uchar * addStr);
-
- info: Appends contents of addStr onto origStr, clipping it at
- 255 characters.
-
- entry: Two Pascal Str255 ptrs.
-
- exit: alters origStr.
- ________________________________________________________________________________*/
- void AppendString( regvar uchar *origStr, regvar uchar *addStr)
- {
- regvar short origLen = *origStr;
- regvar short addLen = *addStr++;
- regvar short newLen;
-
- if (origLen + addLen > 255) // Prevent overwriting memory
- {
- newLen = 255;
- addLen = 255 - origLen;
- }
- else
- newLen = origLen + addLen;
-
-
- *origStr++ = newLen; // Increase size
- origStr += origLen; // Append on end
-
- while (addLen--)
- *origStr++ = *addStr++;
- }
-
-